/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MyIM.client.engine;

import MyIM.client.Client;
import MyIM.client.callback.CallBackRemote;
import MyIM.client.callback.CallBackRemoteObject;
import MyIM.client.view.form.Dialog_Chat;
import MyIM.component.Friend;
import MyIM.component.Group;
import MyIM.server.engine.ServerEngine;
import MyIM.server.engine.ServerModel;
import MyIM.utilities.Status;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.String;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author satthuvdh
 */
public class Engine {

    private Client client;
    private ServerModel server;
    private CallBackRemote callback;

    public Engine() {

        try {
            callback = new CallBackRemoteObject(this);
            this.server = (ServerModel) Naming.lookup(ServerEngine.REMOTE_OBJECT_URL);
        } catch (NotBoundException | MalformedURLException | RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Status login(String username, String password) throws RemoteException {
        Status status = server.login(username, password, callback);
        if (status.compareTo(Status.SUCCESS) == 0) {
            client = new Client(server.getIdFromUsername(username), username, server.getDisplayName(username), server.getAvatar(username));
            server.initUserInfomation(username, callback);
            client.setFriendList(server.getFriendList(server.getIdFromUsername(username)));
        }
        return status;

    }

    public Status register(String username, String password, String displayName,
            String imageURL) throws RemoteException, FileNotFoundException {
        File image;
        if (imageURL.length() == 0) {
            image = new File("images/contact.png");
        } else {
            image = new File(imageURL);
        }
        Status status = server.registering(username, password, displayName, image);
        return status;
    }

    public void logout() throws RemoteException {
        server.logout(client.getUID());
    }

    public Status addFriend(String friendUsername, String groupName) {
        try {
            int fui = server.getIdFromUsername(friendUsername);
            if (fui == -1) {
                return Status.USER_NOT_EXIST;
            }
            ArrayList<Group> list = client.getFriendList();
            for (Group group : list) {
                if (group.getGroupName().compareTo(groupName) == 0) {
                    return server.addFriend(client.getUID(), fui, group.getGroupId());
                }
            }
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Status.FAIL;

    }

    public void removeFriend(String username, String friendUsername) {
        try {
            server.removeFriend(client.getUID(), server.getIdFromUsername(friendUsername));
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Status addGroup(String groupName) {
        try {
            int gid = server.getGroupIdByName(groupName, this.client.getUID());
            if (gid > 0) {
                return Status.GROUP_EXIST;
            } else {
                Status s = server.addGroup(groupName, client.getUID());
                if (s == Status.SUCCESS) {
                    client.setFriendList(server.getFriendList(client.getUID()));
                } else {
                    System.out.println("ERROR ADD GROUP ENGINE FILE");
                }
                return s;
            }
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Status.FAIL;
    }

    public Client getClient() {
        return client;
    }

    public String[] getGroupNameList() {
        return client.getGroupNameList();
    }

    public Status checkFriendExist(String friendName) {
        try {
            int fid = server.getIdFromUsername(friendName);
            if (fid <= 0) {
                return Status.USER_NOT_EXIST;
            } else {
                return Status.USER_EXIST;
            }
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Status.USER_NOT_EXIST;
    }

    public Status sendAddFriendRequest(String friendName, String groupName) {
        try {
            int fid = server.getIdFromUsername(friendName);
            if (fid <= 0) {
                return Status.USER_NOT_EXIST;
            } else {
                int uid = this.client.getUID();
                int gid = -1;
                for (Group group : this.client.getFriendList()) {
                    if (group.getGroupName().equalsIgnoreCase(groupName)) {
                        gid = group.getGroupId();
                        break;
                    }
                }
                if (gid < 0) {
                    return Status.FAIL;
                } else {
                    Status s = server.sendAddFriendRequest(this.client.getUID(), fid, gid);
                    client.setFriendList(server.getFriendList(client.getUID()));
                    return s;
                }
            }
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Status.FAIL;
    }

    public Group getGroupByName(String groupName) {
        try {
            return server.getGroupByName(groupName, client.getUID());
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public void addGroupByName(String groupName) {
        Group g = getGroupByName(groupName);
        if (g != null) {
            client.addGroupObj(g);
        } else {
            System.out.println("group is null");
        }
    }

    public void addNewDialogChat(int fid, Dialog_Chat dialog) {
        client.addNewDialogChat(fid, dialog);
    }

    public ServerModel getServer() {
        return server;
    }

    public Friend getFriend(int uid) {
        try {
            return server.getFriend(uid);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public void sendMessage(int from, int to, String message) {
        try {
            server.sendMessage(from, to, message);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void removeDialogChat(int fid) {
        client.getListChat().remove(fid);
    }

    public Status renameGroup(int uid, int groupId, String text) {
        try {
            return server.renameGroup(uid, groupId, text);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
            return Status.FAIL;
        }

    }

    public void initFriendList(String username) {
        try {
            client.setFriendList(server.getFriendList(server.getIdFromUsername(username)));
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void sendMessageConference(int ownerid, String conferenceName, int from, String message, ArrayList<Friend> attendees) {
        try {
            server.sendMessageConf(ownerid, conferenceName, from, attendees, message);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Status inviteConference(int ownerid, String conferenceName, ArrayList<Friend> attendees, int uid) {
        try {
            for (Friend friend : attendees) {
                if (friend.getUid() == uid) {

                    JOptionPane.showMessageDialog(null, "User already added!!!!", "Warning", JOptionPane.WARNING_MESSAGE);
                    return Status.USER_EXIST;
                }
            }
            Status status = server.inviteConference(ownerid, conferenceName, attendees, uid);
            if (status == Status.USER_OFFLINE) {
                JOptionPane.showMessageDialog(null, "User Offline!!!!", "Warning", JOptionPane.WARNING_MESSAGE);
            } else if (status == Status.FAIL) {
                JOptionPane.showMessageDialog(null, "Invitation denied!!!");
            }
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Status.FAIL;
    }

    public Status moveFriend(int uid, int fid, int gid) {
        try {
            return server.moveFriend(uid, fid, gid);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
            return Status.FAIL;
        }
    }

    public void exitConference(int ownerID, String conferenceName, int uid, ArrayList<Friend> attendees) {
        getClient().getListConference().remove(ownerID + "" + conferenceName);
        int index = -1;
        for (int i = 0; i < attendees.size(); i++) {
            if (attendees.get(i).getUid() == uid) {
                index = i;
            }
        }

        if (index >= 0) {
            attendees.remove(index);
        }

        try {
            server.exitConference(ownerID, conferenceName, attendees);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String getPassword(int uid) {
        try {
            return server.getPassword(uid);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public void changeDisplayname(int uid, String displayName) {
        try {
            server.changeDisplay(uid, displayName);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void changeAvatar(int uid, String filePath) {
        File avatar = new File(filePath);
        try {
            server.changeAvatar(uid, avatar);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void changePassword(int uid, String password) {
        try {
            server.changePassword(uid, password);
        } catch (RemoteException ex) {
            Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
